﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace TuringVM.Core
{
    public class Tape
    {
        private byte[] _positive = new byte[8];
        private byte[] _negative = new byte[8];

        private long _position;
        private byte[] _current;
        private long _currentPosition;

        private delegate void Do();

        public Tape()
        {
            _current = _positive;
        }

        public long Position
        {
            get { return _position; }
            set { MoveTo(value); }
        }

        public byte Value
        {
            get { return _current[_currentPosition]; }
            set { _current[_currentPosition] = value; }
        }

        public void MoveTo(long position)
        {
            if (position > 100)
            {

            }
            _position = position;
            if (position >= 0)
            {
                _current = _positive;
                _currentPosition = position;
                if (_currentPosition >= _positive.Length)
                {
                    Array.Resize(ref _positive, (int)_currentPosition * 2);    //todo: smarter resizing strategy
                    _current = _positive;
                }
            }
            else
            {
                _current = _negative;
                _currentPosition = -position - 1;   // item at '-1' is actually at '0' in _negative
                if (_currentPosition >= _negative.Length)
                {
                    Array.Resize(ref _negative, (int)_currentPosition * 2);    //todo: smarter resizing strategy 
                    _current = _negative;
                }
            }
            
        }

        public void MoveBy(long shift)
        {
            MoveTo(_position + shift);
        }

        public void Fill(IEnumerable<byte> content, long startPosition = 0)
        {
            long oldPosition = _position;
            long pos = startPosition;
            foreach (byte b in content)
            {
                MoveTo(pos);
                Value = b;
                pos++;
            }
            MoveTo(oldPosition);
        }
    }
}
